/**
 *Copyright (c) 2024 watereyes
 * safetymanagement is licensed under Mulan PubL v2.
 * You can use this software according to the terms and conditions of the Mulan
 * PubL v2.
 * You may obtain a copy of Mulan PubL v2 at:
 *          http://license.coscl.org.cn/MulanPubL-2.0
 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
 * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
 * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
 * See the Mulan PubL v2 for more details.
 */
package com.koron.scene.service.impl;


import com.alibaba.fastjson.JSONObject;
import com.google.gson.Gson;
import com.koron.common.bean.StaffBean;
import com.koron.common.dfs.FastDFSClientWrapper;
import com.koron.common.domain.DataBean;
import com.koron.common.util.DocConverterUtils;

import com.koron.scene.domain.ProjectCertificate;
import com.koron.scene.mapper.*;
import com.koron.scene.service.api.ProjectCertificateService;
import com.koron.scene.utils.BaseEntityUtil;
import com.koron.scene.utils.BusinessCode;
import com.koron.scene.utils.DateUtil;
import com.koron.scene.utils.ExcelUtil;

import org.apache.commons.lang3.StringUtils;
import org.apache.poi.ss.usermodel.CellType;
import org.apache.poi.xssf.usermodel.XSSFCell;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.koron.ebs.mybatis.SessionFactory;
import org.quartz.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import org.swan.bean.MessageBean;



import java.io.InputStream;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

@Service
public class ProjectCertificateServiceImpl implements ProjectCertificateService, InitializingBean {

    private static final Logger logger = LoggerFactory.getLogger(ProjectCertificateServiceImpl.class);

    @Autowired
    private FastDFSClientWrapper clientWrapper;

    @Autowired
    private Scheduler scheduler;
    
    @Autowired
    private DocConverterUtils docConverterUtils;
    
    //行转换
    private ProjectCertificate parseRow(XSSFRow row, StaffBean user, String projectId, String enterpriseId)
            throws Exception {
        Date now = new Date();
        ProjectCertificate projectCertificate = new ProjectCertificate();
        projectCertificate.setProjectId(projectId);
        projectCertificate.setEnterpriseId(enterpriseId);
//        人员
        String name = ExcelUtil.getCellValue(row.getCell(0));
//        身份证
        XSSFCell cell = row.getCell(1);
        String idCardNumber = ExcelUtil.getCellValue(cell);
        if (cell != null && cell.getCellTypeEnum() == CellType.NUMERIC) {
            BigDecimal db = new BigDecimal(idCardNumber);
            idCardNumber = db.toPlainString();
        }
//        岗位
        String station = ExcelUtil.getCellValue(row.getCell(2));
//        证书名称
        String certificateName = ExcelUtil.getCellValue(row.getCell(3));
//        证书状态
        String stateStr = ExcelUtil.getCellValue(row.getCell(4));
//        有效日期
        String expiryDateStr = ExcelUtil.getCellValue(row.getCell(5));
        if (StringUtils.isBlank(name)) {
            return null;
        } else {
            projectCertificate.setName(name);
        }
        if (StringUtils.isBlank(idCardNumber)) {
            return null;
        } else {
            projectCertificate.setIdCardNumber(idCardNumber);
        }
        if (StringUtils.isBlank(certificateName)) {
            return null;
        } else {
            projectCertificate.setCertificateName(certificateName);
        }
        projectCertificate.setStation(station);
        if ("缺失".equals(stateStr)) {
            projectCertificate.setState(2);
        } else if ("有效".equals(stateStr) || stateStr == null) {
            projectCertificate.setState(0);
        } else if ("过期".equals(stateStr)) {
            projectCertificate.setState(1);
        } else {
            projectCertificate.setState(2);
        }
        Date expiryDate = DateUtil.formatStringToDate(expiryDateStr, DateUtil.DATE_FORMAT_YMD);
        if (expiryDate == null) {
            projectCertificate.setExpiryDate(null);
            projectCertificate.setState(2);
        } else if (expiryDate.after(now)) {
            projectCertificate.setExpiryDate(expiryDate);
            projectCertificate.setState(0);
        } else {
            projectCertificate.setExpiryDate(expiryDate);
            projectCertificate.setState(1);
        }
        BaseEntityUtil.setAddBaseProperties(projectCertificate, user);
        return projectCertificate;
    }

    @Override
    public MessageBean<?> importFromExcel(StaffBean user, MultipartFile file, String projectId, String enterpriseId) {
        MessageBean<?> msg = MessageBean.create(BusinessCode.SUCCESS.getCode(), BusinessCode.SUCCESS.getDescription(), Object.class);
        if (StringUtils.isBlank(projectId) || StringUtils.isBlank(enterpriseId)) {
            msg.setCode(BusinessCode.INSUFFICIENT_PARAM.getCode());
            msg.setDescription(BusinessCode.INSUFFICIENT_PARAM.getDescription());
            return msg;
        }
        String filePath = null;
        SessionFactory factory = new SessionFactory();
        try {
            ProjectCertificateMapper mapper = factory.getMapper(ProjectCertificateMapper.class);
            //先将文件上传到文件服务器
            if (null == file) {
                msg.setCode(22001);
                msg.setDescription("上传文件为空");
                return msg;
            }
            String fileName = file.getOriginalFilename();
            filePath = clientWrapper.uploadFile(file) + "#" + fileName;//文件上传的路径
            //处理excel中的内容
            InputStream inputStream = file.getInputStream();
            XSSFWorkbook workbook = new XSSFWorkbook(inputStream);
            if (null == workbook) {
                logger.error("上传文件为空");
                msg.setCode(22001);
                msg.setDescription("上传文件为空");
                return msg;
            }
            XSSFSheet sheet = workbook.getSheetAt(0);
            if (sheet == null) {
                logger.error("上传文件为空");
                msg.setCode(22001);
                msg.setDescription("上传文件为空");
                return msg;
            }
            List<ProjectCertificate> projectStaffList = new ArrayList<>();
            int rowsNum = sheet.getPhysicalNumberOfRows();
            for (int i = 1; i < rowsNum; i++) {
                XSSFRow row = sheet.getRow(i);
                ProjectCertificate projectCertificate = parseRow(row, user, projectId, enterpriseId);
                if (projectCertificate != null) {
                    projectStaffList.add(projectCertificate);
                }
            }
            if (projectStaffList != null && projectStaffList.size() > 0) {
                List<ProjectCertificate> insertList = new ArrayList<>();
                //新导入的去重
                List<ProjectCertificate> newDistinctList = new ArrayList<>();
                for (ProjectCertificate p : projectStaffList) {
                    boolean result = newDistinctList.stream().anyMatch(np -> p.getIdCardNumber().equals(np.getIdCardNumber()) && p.getCertificateName().equals(np.getCertificateName()));
                    if (!result) {
                        newDistinctList.add(p);
                    }
                }
                //获取已经保存的证照
                List<ProjectCertificate> exitList = mapper.queryList(null, null, projectId, enterpriseId, null, null);
                if (exitList != null && exitList.size() > 0) {
                    List<ProjectCertificate> sameList = new ArrayList<>();
                    for (ProjectCertificate p : exitList) {
                        for (ProjectCertificate sp : newDistinctList) {
                            if (p.getIdCardNumber().equals(sp.getIdCardNumber()) && p.getCertificateName().equals(sp.getCertificateName())) {
                                sameList.add(sp);
                                //更新已存在的
                                ProjectCertificate up = new ProjectCertificate();
                                up.setName(sp.getName());
                                up.setStation(sp.getStation());
                                up.setState(sp.getState());
                                up.setExpiryDate(sp.getExpiryDate());
                                up.setId(p.getId());
                                BaseEntityUtil.setUpdateBaseProperties(up, user);
                                mapper.updateByPrimaryKeySelective(up);
                            }
                        }
                    }
                    if (sameList != null && sameList.size() > 0) {
                        insertList = newDistinctList.stream().filter(np -> !sameList.stream().anyMatch(sp -> np.getIdCardNumber().equals(sp.getIdCardNumber()) && np.getCertificateName().equals(sp.getCertificateName()))).collect(Collectors.toList());
                    }
                } else {
                    insertList = newDistinctList;
                }

                if (insertList != null && insertList.size() > 0) {
                    mapper.insertList(insertList);
                }
            }
        } catch (
                Exception e) {
            logger.error(e.getMessage(),e);
            if (!StringUtils.isEmpty(filePath)) {
                clientWrapper.deleteFile(filePath.split("#")[0]);
            }
            msg.setCode(BusinessCode.FAILURE.getCode());
            msg.setDescription(BusinessCode.FAILURE.getDescription());
            factory.close(false);
        } finally {
            if (factory != null) {
                factory.close();
            }
        }
        return msg;
    }

    @Override
    public MessageBean<?> importFromFiles(StaffBean user, MultipartFile[] files, String projectId, String enterpriseId) {
        MessageBean<?> msg = MessageBean.create(BusinessCode.SUCCESS.getCode(), BusinessCode.SUCCESS.getDescription(), Object.class);
        if (StringUtils.isBlank(projectId) || StringUtils.isBlank(enterpriseId)) {
            msg.setCode(BusinessCode.INSUFFICIENT_PARAM.getCode());
            msg.setDescription(BusinessCode.INSUFFICIENT_PARAM.getDescription());
            return msg;
        }
        List<String> filePaths = new ArrayList<>();
        SessionFactory factory = new SessionFactory();
        try {
            ProjectCertificateMapper mapper = factory.getMapper(ProjectCertificateMapper.class);
            //先将文件上传到文件服务器
            if (files == null || files.length <= 0) {
                msg.setCode(BusinessCode.INSUFFICIENT_PARAM.getCode());
                msg.setDescription(BusinessCode.INSUFFICIENT_PARAM.getDescription());
                return msg;
            }
            for (MultipartFile file : files) {
                String fileName = null;
                String originalFileName = file.getOriginalFilename();
                int dot = originalFileName.lastIndexOf('.');
                if ((dot > -1) && (dot < (originalFileName.length()))) {
                    fileName = originalFileName.substring(0, dot);
                } else {
                    fileName = originalFileName;
                }
                if (StringUtils.isBlank(fileName)) {
                    break;
                }
                String[] names = fileName.split("_");
                if (names == null || names.length < 2) {
                    break;
                }
                String idCardNumber = names[0];
                String certificateName = names[1];
                ProjectCertificate projectCertificate = mapper.findByCertificateName(projectId, enterpriseId, idCardNumber, certificateName);
                if (projectCertificate != null) {
                    String filePath = clientWrapper.uploadFile(file) + "#" + originalFileName;//文件上传的路径
                    ProjectCertificate up = new ProjectCertificate();
                    String orgAttachment = projectCertificate.getAttachment();
                    List<String> orgList = null;
                    if (StringUtils.isNotBlank(orgAttachment)) {
                        orgList = JSONObject.parseArray(orgAttachment, String.class);
                    }
                    if (orgList == null) {
                        orgList = new ArrayList<>();
                    }
                    orgList.add(filePath);

                    String orgPreAttachment = projectCertificate.getPreviewAttachment();
                    List<String> orgPreList = null;
                    if (StringUtils.isNotBlank(orgPreAttachment)) {
                        orgPreList = JSONObject.parseArray(orgPreAttachment, String.class);
                    }
                    if (orgPreList == null) {
                        orgPreList = new ArrayList<>();
                    }
                    String pdfFilePath = docConverterUtils.converterUpdate(file);
                    if (pdfFilePath != null) {
                        orgPreList.add(pdfFilePath);
                    } else {
                        orgPreList.add(filePath);
                    }
                    up.setId(projectCertificate.getId());
                    up.setAttachment((orgList == null || orgList.isEmpty()) ? null : new Gson().toJson(orgList));
                    up.setPreviewAttachment((orgPreList == null || orgPreList.isEmpty()) ? null : new Gson().toJson(orgPreList));
                    BaseEntityUtil.setUpdateBaseProperties(up, user);
                    mapper.updateByPrimaryKeySelective(up);
                    filePaths.add(filePath);
                }
            }
        } catch (Exception e) {
            if (filePaths != null && !filePaths.isEmpty()) {
                for (String p : filePaths) {
                    clientWrapper.deleteFile(p.split("#")[0]);
                }
            }
            msg.setCode(BusinessCode.FAILURE.getCode());
            msg.setDescription(BusinessCode.FAILURE.getDescription());
            factory.close(false);
        } finally {
            if (factory != null) {
                factory.close();
            }
        }
        return msg;
    }

    @Override
    public MessageBean<?> list(StaffBean user, String staffName, Integer state, String projectId, String enterpriseId, Integer page, Integer pageSize) {
        MessageBean<DataBean> msg = MessageBean.create(BusinessCode.SUCCESS.getCode(), BusinessCode.SUCCESS.getDescription(), DataBean.class);
        try (SessionFactory factory = new SessionFactory()) {
            ProjectCertificateMapper mapper = factory.getMapper(ProjectCertificateMapper.class);
            Integer start = null;
            if (page != null && pageSize != null && page > 0 && pageSize > 0) {
                start = (page - 1) * pageSize;
            }
            List<ProjectCertificate> projectCertificateList = mapper.queryList(staffName, state, projectId, enterpriseId, start, pageSize);
            int total = mapper.queryListTotal(staffName, state, projectId, enterpriseId);
            DataBean dataBean = new DataBean();
            dataBean.setList(projectCertificateList);
            dataBean.setTotalNumber(total);
            dataBean.setPageNo(page);
            dataBean.setPageSize(pageSize);
            dataBean.setTotalPage(start == null ? null : total % pageSize == 0 ? total / pageSize : (total / pageSize + 1));
            msg.setData(dataBean);
        } catch (Exception e) {
            logger.error(e.getMessage(),e);
            msg.setCode(BusinessCode.FAILURE.getCode());
            msg.setDescription(BusinessCode.FAILURE.getDescription());
        }
        return msg;
    }

    @Override
    public MessageBean<?> update(StaffBean user, MultipartFile[] files, String projectCertificateId,
                                 String name, String certificateName, String expiryDateStr,
                                 String keepPathListStr, String deletePathListStr,
                                 String keepPrePathListStr, String deletePrePathListStr) {
        MessageBean<?> msg = MessageBean.create(BusinessCode.SUCCESS.getCode(), BusinessCode.SUCCESS.getDescription(), Object.class);
        SessionFactory factory = new SessionFactory();
        List<String> newFilePaths = new ArrayList<>();
        List<String> newPreFilePaths = new ArrayList<>();
        try {
            ProjectCertificateMapper certificateMapper = factory.getMapper(ProjectCertificateMapper.class);
            if (StringUtils.isBlank(projectCertificateId)) {
                msg.setCode(BusinessCode.INSUFFICIENT_PARAM.getCode());
                msg.setDescription(BusinessCode.INSUFFICIENT_PARAM.getDescription());
                return msg;
            }

            ProjectCertificate oldCertificate = certificateMapper.selectByPrimaryKey(projectCertificateId);
            if (oldCertificate == null) {
                msg.setCode(BusinessCode.PROJECT_CERTIFICATE_NOT_EXIST.getCode());
                msg.setDescription(BusinessCode.PROJECT_CERTIFICATE_NOT_EXIST.getDescription());
                return msg;
            }
            ProjectCertificate upc = new ProjectCertificate();
            upc.setId(oldCertificate.getId());
            if (StringUtils.isNotBlank(expiryDateStr)) {
                Date expiryDate = DateUtil.formatStringToDate(expiryDateStr, DateUtil.DATE_FORMAT_YMD);
                if (expiryDate != null && expiryDate.after(new Date())) {
                    upc.setExpiryDate(expiryDate);
                    upc.setState(0);
                } else if (expiryDate != null && expiryDate.before(new Date())) {
                    upc.setExpiryDate(expiryDate);
                    upc.setState(1);
                }
            }
            upc.setCertificateName(certificateName);
            BaseEntityUtil.setUpdateBaseProperties(upc, user);

            //保存附件
            String[] keepAddressArray = StringUtils.isEmpty(keepPathListStr) ? null : keepPathListStr.split("[,，]");
            List<String> keepAddressList = new ArrayList<>();
            if (keepAddressArray != null && keepAddressArray.length > 0) {
                keepAddressList = Arrays.asList(keepAddressArray).stream().collect(Collectors.toList());
            }
            String[] keepPreAddressArray = StringUtils.isEmpty(keepPrePathListStr) ? null : keepPrePathListStr.split("[,，]");
            List<String> keepPreAddressList = new ArrayList<>();
            if (keepPreAddressArray != null && keepPreAddressArray.length > 0) {
                keepPreAddressList = Arrays.asList(keepPreAddressArray).stream().collect(Collectors.toList());
            }
            if (files != null && files.length > 0) {
                for (MultipartFile file : files) {
                    if (file != null) {
                        String url = clientWrapper.uploadFile(file);
                        String filPath = url + "#" + file.getOriginalFilename();
                        keepAddressList.add(filPath);
                        newFilePaths.add(filPath);
//                        File pdfFile = DocConverterUtils.converter(file);
                        String pdfPath=docConverterUtils.converterUpdate(file);
                        if (pdfPath != null) {
//                            String pdfFilePath = clientWrapper.uploadFile(new FileInputStream(pdfFile), pdfFile.length(), FilenameUtils.getExtension(pdfFile.getName()));
                            keepPreAddressList.add(pdfPath);
                            newFilePaths.add(pdfPath);
                        } else {
                            keepPreAddressList.add(filPath);
                            newFilePaths.add(filPath);
                        }
                    }
                }
            }
            upc.setAttachment((keepAddressList == null || keepAddressList.size() <= 0) ? null : new Gson().toJson(keepAddressList));
            upc.setPreviewAttachment((keepPreAddressList == null || keepPreAddressList.size() <= 0) ? null : new Gson().toJson(keepPreAddressList));
            certificateMapper.updateByPrimaryKeySelective(upc);

            //删除去除的附件
            if (StringUtils.isNotEmpty(deletePathListStr)) {
                String[] delArray = deletePathListStr.split("[,，]");
                for (String delAdr : delArray) {
                    clientWrapper.deleteFile(delAdr.split("#")[0]);
                }
            }
            if (StringUtils.isNotEmpty(deletePrePathListStr)) {
                String[] delArray = deletePrePathListStr.split("[,，]");
                for (String delAdr : delArray) {
                    clientWrapper.deleteFile(delAdr.split("#")[0]);
                }
            }
        } catch (Exception e) {
            if (newFilePaths != null && !newFilePaths.isEmpty()) {
                for (String p : newFilePaths) {
                    clientWrapper.deleteFile(p.split("#")[0]);
                }
            }
            if (newPreFilePaths != null && !newPreFilePaths.isEmpty()) {
                for (String p : newPreFilePaths) {
                    clientWrapper.deleteFile(p.split("#")[0]);
                }
            }
            logger.error(e.getMessage(),e);
            msg.setCode(BusinessCode.FAILURE.getCode());
            msg.setDescription(BusinessCode.FAILURE.getDescription());
            factory.close(false);
            return msg;
        } finally {
            if (factory != null) {
                factory.close();
            }
        }
        return msg;
    }

    @Override
    public MessageBean<?> delete(String projectCertificateId) {
        MessageBean<?> msg = MessageBean.create(BusinessCode.SUCCESS.getCode(), BusinessCode.SUCCESS.getDescription(), Object.class);
        SessionFactory factory = new SessionFactory();
        try {
            ProjectCertificateMapper certificateMapper = factory.getMapper(ProjectCertificateMapper.class);
            ProjectCertificate certificate = certificateMapper.selectByPrimaryKey(projectCertificateId);
            if (certificate != null) {
                certificateMapper.deleteByPrimaryKey(projectCertificateId);
                if (StringUtils.isNotBlank(certificate.getAttachment())) {
                    List<String> pathList = JSONObject.parseArray(certificate.getAttachment(), String.class);
                    if (pathList != null && !pathList.isEmpty()) {
                        for (String p : pathList) {
                            clientWrapper.deleteFile(p.split("#")[0]);
                        }
                    }
                }
                if (StringUtils.isNotBlank(certificate.getPreviewAttachment())) {
                    List<String> pathList = JSONObject.parseArray(certificate.getPreviewAttachment(), String.class);
                    if (pathList != null && !pathList.isEmpty()) {
                        for (String p : pathList) {
                            clientWrapper.deleteFile(p.split("#")[0]);
                        }
                    }
                }
            }

        } catch (Exception e) {
            logger.error(e.getMessage(),e);
            msg.setCode(BusinessCode.FAILURE.getCode());
            msg.setDescription(BusinessCode.FAILURE.getDescription());
            factory.close(false);
            return msg;
        } finally {
            if (factory != null) {
                factory.close();
            }
        }
        return msg;
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        try {
            scheduler.start();
            CronScheduleBuilder cronScheduleBuilder = CronScheduleBuilder
                    .cronSchedule("0 0 0 */1 * ?");

            JobDetail job = JobBuilder.newJob(ProjectCertificateJob.class).withIdentity("job", "ProjectCertificateJob")
                    .build();
            Trigger trigger = TriggerBuilder.newTrigger().withIdentity("job", "ProjectCertificateJob").withSchedule(cronScheduleBuilder).build();
            // Tell quartz to schedule the job using our trigger
            scheduler.scheduleJob(job, trigger);
        } catch (Exception e) {
            logger.error("相关方证照过期检验发生异常" + e.getMessage());
        }
    }
}
